package com.newshub.monitor.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.newshub.monitor.config.MonitorProperties;
import com.newshub.monitor.service.PerformanceAnalysisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.file.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 性能分析服务实现类
 */
@Slf4j
@Service
public class PerformanceAnalysisServiceImpl implements PerformanceAnalysisService {

    private final ObjectMapper objectMapper = new ObjectMapper();
    
    @Autowired
    private MonitorProperties monitorProperties;

    @Override
    public Map<String, Object> getSlowQueries(String sqlType, String tableName,
                                             LocalDateTime startTime, LocalDateTime endTime,
                                             Integer pageNum, Integer pageSize) {
        try {
            String logFile = getTodayLogFile();
            List<JsonNode> logs = readLogFile(logFile);
            
            // 过滤慢查询（执行时间超过100ms）
            List<Map<String, Object>> slowQueries = logs.stream()
                .filter(log -> log.has("executionTime") && !log.path("executionTime").isNull())
                .filter(log -> log.path("executionTime").asLong() > 100)
                .map(log -> {
                    Map<String, Object> query = new HashMap<>();
                    query.put("timestamp", log.path("timestamp").asText());
                    query.put("methodName", log.path("methodName").asText());
                    query.put("className", log.path("className").asText());
                    query.put("executionTime", log.path("executionTime").asLong());
                    query.put("requestUrl", log.path("requestUrl").asText("N/A"));
                    query.put("requestId", log.path("requestId").asText("N/A"));
                    return query;
                })
                .sorted((a, b) -> Long.compare((Long) b.get("executionTime"), (Long) a.get("executionTime")))
                .collect(Collectors.toList());
            
            // 分页处理
            int total = slowQueries.size();
            int start = (pageNum - 1) * pageSize;
            int end = Math.min(start + pageSize, total);
            
            List<Map<String, Object>> pageQueries = slowQueries.subList(start, end);
            
            Map<String, Object> result = new HashMap<>();
            result.put("list", pageQueries);
            result.put("total", total);
            result.put("pageNum", pageNum);
            result.put("pageSize", pageSize);
            
            return result;
            
        } catch (Exception e) {
            log.error("获取慢查询列表失败", e);
            throw new RuntimeException("获取慢查询列表失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> getSlowQueryStats(LocalDateTime startTime, LocalDateTime endTime) {
        try {
            String logFile = getTodayLogFile();
            List<JsonNode> logs = readLogFile(logFile);
            
            // 获取所有有执行时间的日志
            List<Long> executionTimes = logs.stream()
                .filter(log -> log.has("executionTime") && !log.path("executionTime").isNull())
                .map(log -> log.path("executionTime").asLong())
                .collect(Collectors.toList());
            
            // 计算慢查询统计
            long totalQueries = executionTimes.size();
            long slowQueries = executionTimes.stream().filter(time -> time > 100).count();
            double avgExecutionTime = executionTimes.stream().mapToLong(Long::longValue).average().orElse(0.0);
            long maxExecutionTime = executionTimes.stream().mapToLong(Long::longValue).max().orElse(0);
            double slowQueryRate = totalQueries > 0 ? (double) slowQueries / totalQueries * 100 : 0.0;
            
            Map<String, Object> stats = new HashMap<>();
            stats.put("totalSlowQueries", slowQueries);
            stats.put("avgExecutionTime", Math.round(avgExecutionTime * 100.0) / 100.0);
            stats.put("maxExecutionTime", maxExecutionTime);
            stats.put("slowQueryRate", Math.round(slowQueryRate * 100.0) / 100.0);
            stats.put("totalQueries", totalQueries);
            
            return stats;
            
        } catch (Exception e) {
            log.error("获取慢查询统计失败", e);
            throw new RuntimeException("获取慢查询统计失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> getSlowQueryTrend(String sqlType, LocalDateTime startTime, 
                                                LocalDateTime endTime, String interval) {
        // TODO: 实现慢查询趋势
        Map<String, Object> trend = new HashMap<>();
        trend.put("trendData", new ArrayList<>());
        trend.put("interval", interval);
        return trend;
    }

    @Override
    public Map<String, Object> getPerformanceReport(LocalDateTime startTime, LocalDateTime endTime, String reportType) {
        // TODO: 实现性能报表
        Map<String, Object> report = new HashMap<>();
        report.put("reportType", reportType);
        report.put("summary", new HashMap<>());
        report.put("details", new ArrayList<>());
        report.put("timestamp", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        return report;
    }

    @Override
    public Map<String, Object> getOptimizationSuggestions() {
        try {
            String logFile = getTodayLogFile();
            List<JsonNode> logs = readLogFile(logFile);
            
            List<Map<String, Object>> suggestions = new ArrayList<>();
            
            // 分析慢查询
            long slowQueryCount = logs.stream()
                .filter(log -> log.has("executionTime") && !log.path("executionTime").isNull())
                .filter(log -> log.path("executionTime").asLong() > 100)
                .count();
            
            if (slowQueryCount > 0) {
                Map<String, Object> suggestion = new HashMap<>();
                suggestion.put("type", "slow_query");
                suggestion.put("title", "发现慢查询");
                suggestion.put("description", "检测到 " + slowQueryCount + " 个慢查询，建议优化相关方法");
                suggestion.put("priority", "high");
                suggestion.put("impact", "high");
                suggestions.add(suggestion);
            }
            
            // 分析异常
            long errorCount = logs.stream()
                .filter(log -> "ERROR".equals(log.path("level").asText()))
                .count();
            
            if (errorCount > 0) {
                Map<String, Object> suggestion = new HashMap<>();
                suggestion.put("type", "error");
                suggestion.put("title", "发现异常");
                suggestion.put("description", "检测到 " + errorCount + " 个异常，建议检查相关代码");
                suggestion.put("priority", "high");
                suggestion.put("impact", "high");
                suggestions.add(suggestion);
            }
            
            // 分析内存使用
            Runtime runtime = Runtime.getRuntime();
            long totalMemory = runtime.totalMemory();
            long freeMemory = runtime.freeMemory();
            long usedMemory = totalMemory - freeMemory;
            double memoryUsage = (double) usedMemory / totalMemory * 100;
            
            if (memoryUsage > 80) {
                Map<String, Object> suggestion = new HashMap<>();
                suggestion.put("type", "memory");
                suggestion.put("title", "内存使用率过高");
                suggestion.put("description", "当前内存使用率 " + Math.round(memoryUsage) + "%，建议检查内存泄漏");
                suggestion.put("priority", "medium");
                suggestion.put("impact", "medium");
                suggestions.add(suggestion);
            }
            
            Map<String, Object> result = new HashMap<>();
            result.put("suggestions", suggestions);
            result.put("priority", suggestions.isEmpty() ? "low" : "medium");
            result.put("estimatedImpact", suggestions.isEmpty() ? "low" : "medium");
            result.put("totalSuggestions", suggestions.size());
            
            return result;
            
        } catch (Exception e) {
            log.error("获取性能优化建议失败", e);
            throw new RuntimeException("获取性能优化建议失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> getDatabaseMetrics() {
        try {
            String logFile = getTodayLogFile();
            List<JsonNode> logs = readLogFile(logFile);
            
            // 统计查询相关指标
            List<Long> executionTimes = logs.stream()
                .filter(log -> log.has("executionTime") && !log.path("executionTime").isNull())
                .map(log -> log.path("executionTime").asLong())
                .collect(Collectors.toList());
            
            long queryCount = executionTimes.size();
            double avgQueryTime = executionTimes.stream().mapToLong(Long::longValue).average().orElse(0.0);
            long slowQueryCount = executionTimes.stream().filter(time -> time > 100).count();
            
            Map<String, Object> metrics = new HashMap<>();
            metrics.put("connectionCount", 10); // 模拟连接数
            metrics.put("activeConnections", 5); // 模拟活跃连接数
            metrics.put("queryCount", queryCount);
            metrics.put("avgQueryTime", Math.round(avgQueryTime * 100.0) / 100.0);
            metrics.put("slowQueryCount", slowQueryCount);
            metrics.put("slowQueryRate", queryCount > 0 ? Math.round((double) slowQueryCount / queryCount * 100 * 100.0) / 100.0 : 0.0);
            
            return metrics;
            
        } catch (Exception e) {
            log.error("获取数据库性能指标失败", e);
            throw new RuntimeException("获取数据库性能指标失败: " + e.getMessage());
        }
    }

    /**
     * 读取日志文件
     */
    private List<JsonNode> readLogFile(String logFile) throws IOException {
        List<JsonNode> logs = new ArrayList<>();
        
        if (!Files.exists(Paths.get(logFile))) {
            return logs;
        }
        
        try (BufferedReader reader = Files.newBufferedReader(Paths.get(logFile))) {
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.trim().isEmpty()) continue;
                
                try {
                    JsonNode logEntry = objectMapper.readTree(line);
                    logs.add(logEntry);
                } catch (Exception e) {
                    continue;
                }
            }
        }
        
        return logs;
    }

    /**
     * 获取今日日志文件路径
     */
    private String getTodayLogFile() {
        return monitorProperties.getTodayLogFilePath();
    }
}
